    ' Copyright 2009, 2010 Massimo Franciosa
    'This file is part of MYLK.

    'MYLK is free software; you can redistribute it and/or modify
    'it under the terms of the GNU General Public License as published by
    'the Free Software Foundation; either version 2 of the License, or
    '(at your option) any later version.

    'Nome-Programma is distributed in the hope that it will be useful,
    'but WITHOUT ANY WARRANTY; without even the implied warranty of
    'MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    'GNU General Public License for more details.

    'You should have received a copy of the GNU General Public License
    'along with Nome-Programma; if not, write to the Free Software
    'Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

Imports System.Windows.Forms

Public MustInherit Class Engine

    ''' <summary>
    ''' state of the player.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public MustOverride ReadOnly Property PlayerStatus() As PlayerState
    Public Enum PlayerState
        Stopped
        Playing
        Paused
    End Enum

    Public Event GoPlay(ByVal bFromPause As Boolean)
    Public Event GoPause()
    Public Event GoStop()
    Public Event Change(ByVal oNewVid As VIDEOINFO)
    Public Event VideoFinish()
    Public Event ChangeTime(ByVal nNewTime As Long)
    Public Event ChangeBytes(ByVal nNewByte As Long)
    Public Event IsReady()
    Public Event SearchFinished(ByVal oVideoList As List(Of VIDEOINFO), ByVal bSingleVideo As Boolean)


    Private sEngineName As String = ""
    ''' <summary>
    ''' name of the engine
    ''' </summary>
    ''' <remarks></remarks>    
    Public ReadOnly Property EngineName() As String
        Get
            Return sEngineName
        End Get
    End Property

    Private bIsReady As Boolean = False
    ''' <summary>
    ''' means that the player is ready to receive commands or not.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property EngineReady() As Boolean
        Get
            Return bIsReady
        End Get
    End Property
    ''' <summary>
    ''' set the EngineReady property.
    ''' </summary>
    ''' <value></value>
    ''' <remarks></remarks>
    Protected WriteOnly Property SetEngineReady() As Boolean
        Set(ByVal value As Boolean)
            bIsReady = value
            If value = True Then RaiseEvent IsReady()
        End Set
    End Property

    Protected oActualVid As VIDEOINFO
    ''' <summary>
    ''' get the VIDEOINFO object of the video that is playing by the engine.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property VideoPlaying() As VIDEOINFO
        Get
            Return oActualVid
        End Get
    End Property

    Private nTotTime As Long
    ''' <summary>
    ''' total time of the video that is playing by the engine
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property TotTime() As Long
        Get
            Return nTotTime
        End Get
    End Property
    ''' <summary>
    ''' set the TotTime property.
    ''' </summary>
    ''' <value></value>
    ''' <remarks></remarks>
    Protected WriteOnly Property SetTotTime() As Long
        Set(ByVal value As Long)
            nTotTime = value
        End Set
    End Property

    Private nTime As Long
    ''' <summary>
    ''' current time of the video that is playing by the engine
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property Time() As Long
        Get
            Return nTime
        End Get
        Set(ByVal value As Long)
            If nTime <> value Then
              SetCurrentTime(value)
              Me.SetTime = value
            End If
        End Set
    End Property
    ''' <summary>
    ''' set the Time property (internal use).
    ''' </summary>
    ''' <value></value>
    ''' <remarks></remarks>
    Protected WriteOnly Property SetTime() As Long
        Set(ByVal value As Long)
          If nTime <> value Then
            nTime = value
            RaiseEvent ChangeTime(value)
          End If
        End Set
    End Property

    Private nTotByte As Long
    ''' <summary>
    ''' size in bytes of the video that is playing by the engine
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property TotByte() As Long
        Get
            Return nTotByte
        End Get
    End Property
    ''' <summary>
    ''' set the TotByte property.
    ''' </summary>
    ''' <value></value>
    ''' <remarks></remarks>
    Protected WriteOnly Property SetTotByte() As Long
        Set(ByVal value As Long)
            nTotByte = value
        End Set
    End Property

    Private nByte As Long
    ''' <summary>
    ''' bytes buffered from the video that is playing by the engine
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property Bytes() As Long
        Get
            Return nByte
        End Get
    End Property
    ''' <summary>
    ''' set the Byte property.
    ''' </summary>
    ''' <value></value>
    ''' <remarks></remarks>
    Protected WriteOnly Property SetByte() As Long
        Set(ByVal value As Long)
          If nByte <> value Then
            nByte = value
            RaiseEvent ChangeBytes(value)
          End If
        End Set
    End Property

    Private WithEvents oPanelVid As Panel
    ''' <summary>
    ''' panel used by the engine to display the video
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Protected Property VideoPanel() As Panel
        Get
            Return oPanelVid
        End Get
        Set(ByVal value As Panel)
            oPanelVid = value
        End Set
    End Property

    Protected MustOverride Sub PlayFromStop(ByVal oVid As VIDEOINFO)
    Protected MustOverride Sub PlayFromPause()
    Protected MustOverride Sub Pause()
    Protected MustOverride Sub StopEsec()
    Protected MustOverride Function SearchVideo(ByVal asKeyWords As String(), ByVal bSingleVideo As Boolean, ByVal nNumRisp As Integer) As List(Of VIDEOINFO)
    Private Delegate Sub SearchDelegate(ByVal asKeyWords As String(), ByVal bSingleVideo As Boolean, ByVal nNumRisp As Integer)
    Public MustOverride Sub SetCurrentTime(ByVal nTime As Integer)
    Public MustOverride Sub Init()
    Public MustOverride Sub SetVolume(ByVal nVolume As Integer)

    Public Sub LaunchSearch(ByVal asKeyWords As String(), ByVal bSingleVideo As Boolean, ByVal nNumRisp As Integer)

        Dim oThread As SearchDelegate = New SearchDelegate(AddressOf ExecSearch)
        oThread.BeginInvoke(asKeyWords, bSingleVideo, nNumRisp, Nothing, Nothing)

    End Sub

    Private Sub ExecSearch(ByVal asKeyWords As String(), ByVal bSingleVideo As Boolean, ByVal nNumRisp As Integer)
        Dim oResults As List(Of VIDEOINFO) = Me.SearchVideo(asKeyWords, bSingleVideo, nNumRisp)
        For Each oVid As VIDEOINFO In oResults
            oVid.EngineName = Me.EngineName
        Next
        RaiseEvent SearchFinished(oResults, bSingleVideo)
    End Sub

    Public Sub StopExecution()
        Me.StopEsec()
        RaiseEvent GoStop()
    End Sub

    Public Sub PlayNew(ByVal oVid As VIDEOINFO)
        Me.PlayFromStop(oVid)
        oActualVid = oVid
        RaiseEvent Change(oVid)
    End Sub

    Public Sub PlayPause()

        Select Case Me.PlayerStatus
            Case PlayerState.Stopped ' if is stopped, it will play
                Me.PlayNew(oActualVid)
                RaiseEvent GoPlay(False)

            Case PlayerState.Playing  '  if is playing, it will pause
                Me.Pause()
                RaiseEvent GoPause()


            Case PlayerState.Paused  ' in is paused it will resume
                Me.PlayFromPause()
                RaiseEvent GoPlay(True)

        End Select

    End Sub

    ''' <summary>
    ''' Raise the event when the video is finished
    ''' </summary>
    ''' <remarks></remarks>
    Protected Sub RaiseVideoFinish()
        RaiseEvent VideoFinish()
    End Sub

    ''' <summary>
    ''' raise the event when the player goes to "playing" status
    ''' </summary>
    ''' <param name="bFromPause">True means that the player status was "Paused", false means the status was "Stopped"</param>
    ''' <remarks></remarks>
    Protected Sub RaiseGoPlay(ByVal bFromPause As Boolean)
        RaiseEvent GoPlay(bFromPause)
    End Sub

    ''' <summary>
    ''' raise the event when the player goes to "paused" status
    ''' </summary>
    ''' <remarks></remarks>
    Protected Sub RaiseGoPause()
        RaiseEvent GoPause()
    End Sub

    ''' <summary>
    ''' raise the event when the player goes to "stopped" status
    ''' </summary>
    ''' <remarks></remarks>
    Protected Sub RaiseGoStop()
        RaiseEvent GoStop()
    End Sub

    ''' <summary>
    ''' raise the event when new video is going to be played
    ''' </summary>
    ''' <param name="oNewVid">the videoinfo object to be playing</param>
    ''' <remarks></remarks>
    Protected Sub RaiseChange(ByVal oNewVid As VIDEOINFO)
        RaiseEvent Change(oNewVid)
    End Sub

    ''' <summary>
    ''' raise the event when the current time is changed
    ''' </summary>
    ''' <param name="nNewTime">new current time, in seconds</param>
    ''' <remarks></remarks>
    Protected Sub RaiseChangeTime(ByVal nNewTime As Integer)
        RaiseEvent ChangeTime(nNewTime)
    End Sub

    ''' <summary>
    ''' raise the event when the bytes downloaded is changed
    ''' </summary>
    ''' <param name="nNewBytes">new current bytes downloaded</param>
    ''' <remarks></remarks>
    Protected Sub RaiseChangeBytes(ByVal nNewBytes As Integer)
        RaiseEvent ChangeBytes(nNewBytes)
    End Sub

    ''' <summary>
    ''' raise the event when the player is ready
    ''' </summary>
    ''' <remarks></remarks>
    Protected Sub RaiseIsReady()
        RaiseEvent IsReady()
    End Sub

  Public Sub New(ByVal oPanelVid_p As Panel, ByVal sEngineName_p As String)
    oPanelVid = oPanelVid_p
    sEngineName = sEngineName_p
  End Sub

End Class
